﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenQuarters.WebQuarters.Utils;
using OpenQuarters.WebQuarters.Core;
using OpenQuarters.WebQuarters.Modules.ItemList;
using RssToolkit.Rss;

namespace OpenQuarters.WebQuarters.Modules.Blog
{
    partial class BlogPost : BlogEntity<BlogPost, long>, IItemListable
    {
        [Newtonsoft.Json.JsonProperty]
        [Orderable, Filterable]
        [PropertyConfiguration(PropertyType.TextBox, SourceField = "Title")]
        public string json_Title
        {
            get { return this.Title; }
            set { this.Title = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        [PropertyConfiguration(PropertyType.HTML, SourceField = "Summary")]
        public string json_Summary
        {
            get { return this.Summary; }
            set { this.Summary = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        [Orderable, Filterable]
        [PropertyConfiguration(PropertyType.DatePicker, SourceField = "DateCreated")]
        public DateTime json_Date_Created
        {
            get { return this.DateCreated; }
            set { this.DateCreated = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        [PropertyConfiguration(PropertyType.HTML, SourceField = "Content")]
        public string json_Content
        {
            get { return this.Content; }
            set { this.Content = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        [Orderable, Filterable]
        [PropertyConfiguration(PropertyType.Hidden, SourceField = "BlogPostId")]
        public long json_BlogPost_Id
        {
            get { return this.BlogPostId; }
            set { this.BlogPostId = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        [Orderable, Filterable]
        [PropertyConfiguration(PropertyType.TextBox, SourceField = "AuthorId")]
        public string json_Author_Id
        {
            get { return this.AuthorId; }
            set { this.AuthorId = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        [Orderable, Filterable]
        [PropertyConfiguration(PropertyType.CheckBox, SourceField = "IsLive")]
        public bool json_Is_Live
        {
            get { return this.IsLive; }
            set { this.IsLive = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        [Orderable, Filterable]
        [PropertyConfiguration(PropertyType.CheckBox, SourceField = "AllowComments")]
        public bool json_Allow_Comments
        {
            get { return this.AllowComments; }
            set { this.AllowComments = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        [Orderable, Filterable]
        [PropertyConfiguration(PropertyType.TextBox)] //, PropertyType.ExistingValueOrNew, OptionSource = "OpenQuarters.WebQuarters.Modules.Blog.BlogInstance.BlogInstances")]
        public string json_BlogInstance
        {
            get { return this.BlogInstance == null ? "" : this.BlogInstance.Name; }
            set
            {
                // If the user has specified the name of a blog instance that
                // does not exist, add this instance if permissions allow

                var instance = BlogInstance.Table.FirstOrDefault(e => e.Name == value);
                if (instance == null && Core.User.Current.HasPermission(Core.Permissions.Entity.Create.SetValue(typeof(BlogInstance).FullName)))
                {
                    instance = new BlogInstance()
                    {
                        Name = value
                    }.Save();
                }
                if (instance == null)
                {
                    this.BlogInstanceId = null;
                }
                else
                {
                    this.BlogInstanceId = instance.BlogInstanceId;
                }
            }
        }

        [Newtonsoft.Json.JsonProperty]
        public List<BlogComment> json_BlogComments_Approved
        {
            get { return this.BlogComments.Where(e => e.Approved).ToList(); }
        }

        [Newtonsoft.Json.JsonProperty]
        [Orderable, Filterable]
        [PropertyConfiguration(PropertyType.TextBox)]
        public string json_Category
        {
            get { return this.Category; }
            set { this.Category = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        [Orderable, Filterable]
        [PropertyConfiguration(PropertyType.TextBox)]
        public string json_Tags
        {
            get { return this.Tags; }
            set { this.Tags = value; }
        }

        public string[] GetTags()
        {
            if (string.IsNullOrEmpty(this.Tags))
                return new string[] { };
            else
                return this.Tags.Replace(" ,", "").Replace(", ", "").Replace("  ", " ").Split(',');
        }

        public override long GetKey(BlogPost Entity)
        {
            return Entity.BlogPostId;
        }

        public override System.Linq.Expressions.Expression<Func<BlogPost, bool>> GetIDSelector(long ID)
        {
            return e => e.BlogPostId == ID;
        }

        public override void OnSaving()
        {
            base.OnSaving();

            if (this.DateCreated == DateTime.MinValue)
            {
                this.DateCreated = DateTime.Now;
            }
        }

        [Url]
        [Newtonsoft.Json.JsonProperty]
        public string Url
        {
            get
            {
                return this.ItemUrl();
            }
        }

        public string ItemUrl()
        {
            StringBuilder sb = new StringBuilder();
            if (ItemListerHelper.CurrentFullViewPage != null)
            {
                sb.Append(ItemListerHelper.CurrentFullViewPage.GetUrl() + "/");
            }
            sb.Append(this.DateCreated.Year.ToString() + "/" + this.DateCreated.Month.ToString().PadLeft(2, Char.Parse("0")) + "/" + this.DateCreated.Day.ToString().PadLeft(2, Char.Parse("0")) + "/");

            sb.Append(Title.ToUrlSafeString());
            return sb.ToString();
        }


        [Newtonsoft.Json.JsonProperty]
        public string HtmlLink
        {
            get
            {
                return @"<a href=""" + Url + @""">" + Title + "</a>";
            }
        }

        [Newtonsoft.Json.JsonProperty]
        public string BackLink
        {
            get
            {
                return GetBackLink(Core.Translation.Translate("Back"));
            }
        }

        public string GetBackLink(string text)
        {
            return @"<a href=""" + ItemListerHelper.CurrentFullViewPage.GetUrl() + @""">" + text + "</a>";
        }

        public string EditLink
        {
            get
            {
                return ItemListModule.GetItemEditLink(this);
            }
        }

        public string DeleteLink
        {
            get
            {
                return ItemListModule.GetItemDeleteLink(this);
            }
        }

        #region IItemListable Members

        public string GetIDAsString()
        {
            return this.BlogPostId.ToString();
        }

        #endregion

        #region IItemListable Members

        public bool IsNewItem()
        {
            return IsNew();
        }

        public IItemListable LoadItem(string ID)
        {
            return Load(ID.ToInt64());
        }

        public IItemListable SaveItem()
        {
            return this.Save();
        }

        public void DeleteItem()
        {
            this.Delete();
        }

        public IItemListable CreateItem<T>(ItemListerControl<T> parentList) where T : class, IItemListable
        {
            // When creating a new blog post item, we need it to have the same
            // BlogInstanceId as the other items so that the user doesn't need
            // to set it manually.
            BlogInstance blogInstance = null;

            // First, look for a filter on the parent list
            var blogInstanceFilter = parentList.Configuration.Filters.FirstOrDefault(i => i.Field == "json_BlogInstance" && i.OperatorName == FilterOperator.Equals);
            if (blogInstanceFilter != null)
            {
                var testInstance = BlogInstance.GetByName(blogInstanceFilter.Value);
                if (testInstance != null)
                {
                    blogInstance = testInstance;
                }
            }
            else if (parentList.Items.Count > 0)
            {
                // There's no filter on the parent list, so let's use the instance that the first item uses
                blogInstance = (parentList.Items[0] as BlogPost).BlogInstance;
            }

            return new BlogPost()
            {
                Title = "New Item",
                DateCreated = DateTime.Now,
                Summary = "Summary",
                Content = "<p>Article</p>",
                AuthorId = Core.User.Current.UserId,
                BlogInstance = blogInstance
            };
        }

        public IQueryable GetQueryableList()
        {
            return DataContext.GetTable<BlogPost>();
        }

        public IItemListable GetItemFromUrl(string url, List<IItemListable> additionalItems)
        {
            try
            {
                foreach (var i in additionalItems)
                {
                    if (url.EndsWith(((BlogPost)i).Url))
                    {
                        return i;
                    }
                }

                List<string> urlParts = url.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries).ToList();
                DateTime dateCreated = new DateTime(
                    Convert.ToInt32(urlParts[urlParts.Count - 4]),
                    Convert.ToInt32(urlParts[urlParts.Count - 3]),
                    Convert.ToInt32(urlParts[urlParts.Count - 2]));
                DateTime dateCreatedEnd = dateCreated.AddDays(1);

                var matchingDates = Table.Where(i => i.DateCreated >= dateCreated && i.DateCreated < dateCreatedEnd);
                foreach (var i in matchingDates)
                {
                    if (i.Title.ToUrlSafeString() == urlParts.Last())
                    {
                        return i;
                    }
                }
            }
            catch { }
            return null;
        }

        public RssToolkit.Rss.RssItem ToRssItem()
        {
            RssItem item = new RssItem();
            item.Title = this.Title;
            item.PubDateParsed = this.DateCreated;
            item.Description = this.Summary;
            item.Link = this.Url;

            //if (this..Length != 0)
            //{
            //    RssCategory category = new RssCategory();
            //    category.Text = this.Category;
            //    item.Categories.Add(category);
            //}

            return item;
        }

        public string ItemTitle()
        {
            return this.Title;
        }
        
        public string MetaKeywords()
        {
            return null;
        }

        public string MetaDescription()
        {
            return this.Summary;
        }

        #endregion
    }
}
